package com.theaf.basemodule.web.controller;

import com.theaf.basemodule.common.api.UserService;
import com.theaf.core.api.model.UserInfo;
import com.theaf.core.cache.ThreadLocalHelper;
import com.theaf.core.shiro.UserRealm;
import com.theaf.core.utils.HttpHelper;
import com.theaf.core.utils.QiniuUtils;
import com.theaf.core.utils.SmExceptionHelper;
import com.theaf.core.utils.StringUtils;
import com.theaf.core.web.ResultHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.theaf.core.shiro.UserRealm.SHIRO_SESSION_PREFIX;


@RestController
@RequestMapping
@Api(description = "登录请求")
public class LoginController {
    private static final String USER_SESSION_MAP = "USER_SESSION_MAP";//用户SESSSION映射

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping(value = "/noAuthent",  method = RequestMethod.GET)
    @ApiOperation(value = "未登录", notes = "未登录")
    public Object loginError(){
        return new HashMap(){{put("state",401);}};
    }

    @RequestMapping(value = "/noPopdom",  method = RequestMethod.GET)
    @ApiOperation(value = "没有权限", notes = "没有权限")
    public Object noAuth(){
        return new HashMap(){{put("state",402);}};
    }
    @RequestMapping(value = "/getUploadToken", method = RequestMethod.GET)
    @ApiOperation(value = "获取七牛的token", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "空间名" , name = "bucket" , dataType = "string" , paramType = "query",required=true),
            @ApiImplicitParam(value = "应用名" , name = "app" , dataType = "string" , paramType = "query",required=true),
            @ApiImplicitParam(value = "TOKEN数量" , name = "keySize" , required = true , dataType = "long" , paramType = "query")
    })
    public Object getUploadToken(String bucket,String app,int keySize){
        String token = QiniuUtils.getUploadToken(app,bucket,null);
        Map map = new HashMap();
        map.put("token",token);
        map.put("domain",QiniuUtils.getUrlByBucket(bucket));
        map.put("expires",QiniuUtils.EXPIRES);
        if(keySize>0) {
            String[] keys = new String[keySize];
            for (int i = 0; i < keySize; i++) {
                keys[i] = UUID.randomUUID().toString().replaceAll("-", "");
            }
            map.put("keys", keys);
        }
        return ResultHandler.success(map);
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ApiOperation(value = "登录", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户名" , name = "userName" , dataType = "string" , paramType = "query",required=true),
            @ApiImplicitParam(value = "密码" , name = "password" , dataType = "string" , paramType = "query",required=true),
            @ApiImplicitParam(value = "终端" , name = "terminal" , required = true , dataType = "string" , paramType = "query" ,allowableValues = "PC,APP,PAD")
    })
    public Object login(String userName , String password,String terminal){
        UsernamePasswordToken tocken = new UsernamePasswordToken(userName,password);
        UserInfo userInfo = userService.login(userName,password);
        userInfo.setTerminal(terminal);
        userInfo.setIp(HttpHelper.getIp(request));
        if(StringUtils.isNotEmpty(userInfo.getAllowIp())
                &&userInfo.getAllowIp().indexOf(userInfo.getIp())<0){
            throw SmExceptionHelper.sysUnknownException("此IP不在允许登录范围内");
        }
        String requestUrl = new String(request.getRequestURL());
        String oldSessionId = (String)redisTemplate.opsForValue().get(USER_SESSION_MAP+userName);
        //PC端下不允许重复登录时要踢出前者用户
        if(terminal.equals(UserInfo.TERMINAL_PC)&&!userInfo.isAlowRepeatLogin()&&oldSessionId!=null){
            redisTemplate.delete(SHIRO_SESSION_PREFIX + oldSessionId);
            redisTemplate.delete(oldSessionId);
        }
        ThreadLocalHelper.set(UserRealm.INLINE_INFO,userInfo);
        Subject subject = SecurityUtils.getSubject();
        subject.login(tocken);
        String sessionId = (String)subject.getSession().getId().toString();
        //手机或平板登录时，在线信息超时时间改为7天
        if(terminal.equals(UserInfo.TERMINAL_APP)||terminal.equals(UserInfo.TERMINAL_PAD)){
            redisTemplate.expire(SHIRO_SESSION_PREFIX + sessionId, 7, TimeUnit.DAYS);
        }
        redisTemplate.opsForValue().set(USER_SESSION_MAP+userName,sessionId);
        redisTemplate.expire(USER_SESSION_MAP+userName, -1, TimeUnit.MINUTES);
        return ResultHandler.success(sessionId);
    }

    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ApiOperation(value = "登出", httpMethod = "POST")
    public Object logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return ResultHandler.success(null);
    }
}
